package objects
{
    import away3DExtensions.ColoredSubGeometry;
    
    import away3d.core.base.IRGBABufferRenderable;
    import away3d.core.base.SubGeometry;
    import away3d.lights.PointLight;
    import away3d.materials.DefaultMaterialBase;
    import away3d.materials.MaterialBase;
    import away3d.materials.methods.BufferColorMethod;
    import away3d.primitives.Plane;
    
    import flash.display.BitmapData;
    import flash.geom.Point;
    
    /**
     * A plane where segment width and height and color values are determined by passed in bitmap data.
     */
    public class BitmapPlane extends Plane
    {
        protected var bitmapData : BitmapData;
        protected var heightMapFunction : Function;
        
        public function BitmapPlane(material:DefaultMaterialBase, width : int, height : int, bitmapData : BitmapData, heightMapFunction : Function = null)
        {
            var _segmentsW : int = bitmapData.width;
            var _segmentsH : int = bitmapData.height;
            
            // Most of these are going to be ignored.
            super(material, width, height, _segmentsW, _segmentsH, true, ColoredSubGeometry);
            
            this.bitmapData = bitmapData;
            
            this.heightMapFunction = heightMapFunction;
            
            material.addMethod(new BufferColorMethod (false, false, false));
        }
        
        /**
         * @inheritDoc
         */
        override protected function buildGeometry(target : SubGeometry) : void
        {
            var vertices : Vector.<Number>;
            var colorVertices : Vector.<Number>;
            var normals : Vector.<Number>;
            var tangents : Vector.<Number>;
            var indices : Vector.<uint>;
            var x : Number, y : Number;
            var numInds : uint;
            var base : uint;
            var tw : uint = _segmentsW+1;
            var numVerts : uint = (_segmentsH + 1) * tw;
            
            if (numVerts == target.numVertices)
            {
                vertices = target.vertexData;
                colorVertices = (target as IRGBABufferRenderable).getRGBAVertices();
                normals = target.vertexNormalData;
                tangents = target.vertexTangentData;
                indices = target.indexData;
            }
            else
            {
                vertices = new Vector.<Number>(numVerts * 3, true);
                colorVertices = new Vector.<Number>(numVerts * 4, true);
                normals = new Vector.<Number>(numVerts * 3, true);
                tangents = new Vector.<Number>(numVerts * 3, true);
                indices = new Vector.<uint>(_segmentsH * _segmentsW * 6, true);
            }
            
            numVerts = 0;
            var numColors : int = 0;
            
            for (var yi : uint = 0; yi <= _segmentsH; ++yi)
            {
                for (var xi : uint = 0; xi <= _segmentsW; ++xi)
                {
                    x = (xi/_segmentsW)*_width;
                    y = (yi/_segmentsH)*_height;
                    
                    var pixel : uint = bitmapData.getPixel32(xi, yi);
                    var b : uint = pixel & 0xFF;
                    var g : uint = (pixel >> 8) & 0xFF; 
                    var r : uint = (pixel >> 16) & 0xFF;
                    var a : uint = (pixel >> 24) & 0xFF;
                    
                    vertices[numVerts] = x;
                    
                    normals[numVerts] = 0;
                    tangents[numVerts++] = 1;
                    
                    colorVertices[numColors++] = (r as Number) / 256;
                    colorVertices[numColors++] = (g as Number) / 256;
                    colorVertices[numColors++] = (b as Number) / 256;
                    colorVertices[numColors++] = (a as Number) / 256;
                    
                    vertices[numVerts] = y;
                    normals[numVerts] = 0;
                    tangents[numVerts++] = 0;
                    
                    vertices[numVerts] = heightMapFunction != null ? heightMapFunction(x, y, pixel) : 1;
                    normals[numVerts] = -1;
                    tangents[numVerts++] = 0;
                    
                    if (xi != _segmentsW && yi != _segmentsH)
                    {
                        base = xi + yi*tw;
                        indices[numInds++] = base;
                        indices[numInds++] = base + tw;
                        indices[numInds++] = base + tw + 1;
                        indices[numInds++] = base;
                        indices[numInds++] = base + tw + 1;
                        indices[numInds++] = base + 1;
                    }
                }
            }
            
            target.updateVertexData(vertices);
            (target as IRGBABufferRenderable).updateRGBAVertices(colorVertices);
            target.updateVertexNormalData(normals);
            target.updateVertexTangentData(tangents);
            target.updateIndexData(indices);
        }
    }
}